<?php
        set_time_limit(0); //бесконечное время ожидания
        
        defined('_JEXEC') or die('Direct Access to this location is not allowed.');
        
        //класс для работы с прокси
        class Proxy
        {       
                const COUNT = 150; //количество максимальных заходов с одного ip
                private $view = 0; //текущее количество заходов
        
                //необходимо новое соединение при создании
                public function __construct()
                {
                        Proxy::NewIdentity();
                }
        
                //новое соединение
                static function NewIdentity($tor_ip='127.0.0.1', $control_port='9051', $auth_code=''){
                        $fp = fsockopen($tor_ip, $control_port, $errno, $errstr, 30);
                        if (!$fp) return false; //невозможно соединиться с control port
        
                        fputs($fp, "AUTHENTICATE $auth_code\r\n");
                        $response = fread($fp, 1024);
                        list($code, $text) = explode(' ', $response, 2);
                        if ($code != '250') return false; //ошибка аутентификации
 
                        //запрос на новое соединение
                        fputs($fp, "signal NEWNYM\r\n");
                        $response = fread($fp, 1024);
                        list($code, $text) = explode(' ', $response, 2);
                        if ($code != '250') return false; //ошибка сигнала
 
                        fclose($fp);
                        return true;
                }
                
                //получить страницу
                public function GetPage($url)
                {       
                        $this->view += 1;
                        if ($this->view > Proxy::COUNT)
                        {
                                Proxy::NewIdentity();
                                $this->view = 1;
                        }
                        $proxy = "127.0.0.1:9050";
                        $ch = curl_init();
                        curl_setopt($ch, CURLOPT_URL, $url);
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                        curl_setopt($ch, CURLOPT_PROXY, $proxy);
                        curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
                        $result = curl_exec($ch);
                        curl_close($ch);
                        Return $result;
                }
        }
        
        //класс для работы с сайтом
        class Reader
        {       
                private $proxy;
        
                public function __construct()
                {
                        $this->proxy = new Proxy();
                }
        
                //массив оригинальных каталогов
                static $cars = array
                (
                        "AUDI"                  => "http://app.autoxp.ru/pscomplex/catalog.aspx?clstep=catalog&mark=audi&salerind=223",
                        "BMW"                   => "http://catalogs.choise.ru/bmw/",
                        "CHEVROLET"     => "http://app.autoxp.ru/pscomplex/catalog.aspx?clstep=catalog&mark=chevrolet&salerind=223",
                        "CITROEN"               => "http://app.autoxp.ru/pscomplex/catalog.aspx?clstep=catalog&mark=citroen&salerind=223",
                        "DAEWOO"                => "http://app.autoxp.ru/pscomplex/catalog.aspx?clstep=catalog&mark=daewoo&salerind=223",
                        "FIAT"                  => "http://app.autoxp.ru/pscomplex/catalog.aspx?clstep=catalog&mark=fiat&salerind=223",
                        "FORD"                  => "http://app.autoxp.ru/pscomplex/catalog.aspx?clstep=catalog&mark=ford&salerind=223",
                        "HONDA"                 => "http://catalogs.choise.ru/honda/",
                        "HYUNDAI"               => "http://catalogs.choise.ru/hyundai/",
                        "KIA"                   => "http://catalogs.choise.ru/kia/",
                        "LEXUS"                 => "http://app.autoxp.ru/pscomplex/catalog.aspx?clstep=catalog&mark=lexus&salerind=223",
                        "MAZDA"                 => "http://catalogs.choise.ru/mazda/",
                        "MERCEDES BENZ" => "http://app.autoxp.ru/pscomplex/catalog.aspx?clstep=catalog&mark=mercl&salerind=223",
                        "MITSUBISHI"    => "http://catalogs.choise.ru/mitsubishi/",
                        "NISSAN"                => "http://catalogs.choise.ru/nissan/",
                        "PEUGEOT"               => "http://app.autoxp.ru/pscomplex/catalog.aspx?clstep=catalog&mark=pego&salerind=223",
                        "PORSCHE"               => "http://app.autoxp.ru/pscomplex/catalog.aspx?clstep=catalog&mark=porsche&salerind=223",
                        "RENAULT"               => "http://app.autoxp.ru/pscomplex/catalog.aspx?clstep=catalog&mark=renault&salerind=223",
                        "SAAB"                  => "http://app.autoxp.ru/pscomplex/catalog.aspx?clstep=catalog&mark=saab&salerind=223",
                        "SSANG YONG"    => "http://app.autoxp.ru/pscomplex/catalog.aspx?clstep=catalog&mark=ssangyong&salerind=223",
                        "SUBARU"                => "http://catalogs.choise.ru/subaru/",
                        "SUZUKI"                => "http://catalogs.choise.ru/suzuki/",
                        "TOYOTA"                => "http://catalogs.choise.ru/toyota/",
                        "VOLKSWAGEN"    => "http://app.autoxp.ru/pscomplex/catalog.aspx?clstep=catalog&mark=vw&salerind=223",
                        "VOLVO"                 => "http://app.autoxp.ru/pscomplex/catalog.aspx?clstep=catalog&mark=volvol&salerind=223"
                );
                
                static $carsNamings = array
                (
                        "AUDI"                  => "audi",
                        "BMW"                   => "bmw",
                        "CHEVROLET"     => "chevrolet",
                        "CITROEN"               => "citroen",
                        "DAEWOO"                => "daewoo",
                        "FIAT"                  => "fiat",
                        "FORD"                  => "ford",
                        "HONDA"                 => "honda",
                        "HYUNDAI"               => "hyundai",
                        "KIA"                   => "kia",
                        "LEXUS"                 => "lexus",
                        "MAZDA"                 => "mazda",
                        "MERCEDES BENZ" => "mercl",
                        "MITSUBISHI"    => "mitsubishi",
                        "NISSAN"                => "nissan",
                        "PEUGEOT"               => "pego",
                        "PORSCHE"               => "porsche",
                        "RENAULT"               => "renault",
                        "SAAB"                  => "saab",
                        "SSANG YONG"    => "ssangyong",
                        "SUBARU"                => "subaru",
                        "SUZUKI"                => "suzuki",
                        "TOYOTA"                => "toyota",
                        "VOLKSWAGEN"    => "vw",
                        "VOLVO"                 => "volvol"
                );
                
                public function UpdateModels()
                {       
                        WorkWithDB::ClearModels();
                
                        echo 'Дата начала '.date("H:i:s").'<br>';
                        foreach(static::$cars as $brend=>$original) //$brend - марка автомобиля, $original - ссылка на каталог оригинальных запчастей
                        {
                                $series = $this->Parser($original, 'serie'); //$serie - серия
                                foreach($series as $serie)
                                {
                                        echo $serie.'<br>';
                                        $mades = $this->Parser($original.'&serie='.$serie, 'made'); //$made - год выпуска
                                        foreach($mades as $made)
                                        {
                                                //echo '->'.$made.'<br>';
                                                $kuzovs = $this->Parser($original.'&serie='.$serie.'&made='.$made, 'kuzov'); //$kuzov - тип кузова
                                                foreach($kuzovs as $kuzov)
                                                {
                                                        //echo '->->'.$kuzov.'<br>';
                                                        $fuels  = $this->Parser($original.'&serie='.$serie.'&made='.$made.'&kuzov='.$kuzov, 'fuel'); //$fuel - тип двигателя
                                                        foreach($fuels as $fuel)
                                                        {
                                                                //echo '->->->'.$fuel.'<br>';
                                                                $motors  = $this->Parser($original.'&serie='.$serie.'&made='.$made.'&kuzov='.$kuzov.'&fuel='.$fuel, 'motor'); //motor - тип двигателя
                                                                foreach($motors as $motor)
                                                                {       
                                                                        //echo '->->->->'.$motor.'<br>';
                                                                        $tcodaxps  = $this->Parser($original.'&serie='.$serie.'&made='.$made.'&kuzov='.$kuzov.'&fuel='.$fuel.'&motor='.$motor, 'tcodaxp'); //$tcodaxp - модель
                                                                        foreach($tcodaxps as $tcodaxp)
                                                                        {
                                                                                //echo '->->->->->'.$original.'&serie='.$serie.'&made='.$made.'&kuzov='.$kuzov.'&fuel='.$fuel.'&motor='.$motor.'&tcodaxp='.$tcodaxp.'<br>';
                                                                                WorkWithDB::AddModel($brend, $serie, $made, $kuzov, $fuel, $motor, $tcodaxp);
                                                                        }
                                                                }
                                                        }
                                                }
                                        }
                                }
                        }
                        echo 'Дата конца '.date("H:i:s").'<br>';
                }
                
                public function UpdatePrice()
                {
                        WorkWithDB::ClearPrices();
                        
                        echo 'Дата начала '.date("H:i:s").'<br>';
                        foreach(static::$carsNamings as $brend=>$naming) //$brend - марка автомобиля, $original - ссылка на каталог оригинальных запчастей
                        {
                                $cods = WorkWithDB::GetCods($brend);
                                foreach($cods as $cod)
                                {
                                        //echo $cod.'<br>';
                                        
                                        //echo "http://app.autoxp.ru/pscomplex/catalog.aspx?clstep=catalog&salerind=223&mark=".$naming."&codaxp=".$cod;
                                        //return;
                                        $grnums = $this->ParserGrnum("http://app.autoxp.ru/pscomplex/catalog.aspx?clstep=catalog&salerind=223&mark=".$naming."&codaxp=".$cod);
                                        foreach($grnums as $grnum_value=>$grnum_href)
                                        {
                                                //echo $grnum_value.' '.$grnum_href.'<br>';
                                                
                                                $pdgrnums = $this->ParserPdgrnum("http://app.autoxp.ru".$grnum_href);
                                                
                                                foreach($pdgrnums as $pdgrnum)
                                                {
                                                        $elems = $this->ParserElemPdgrnum("http://app.autoxp.ru".$pdgrnum);     
                                                        foreach($elems as $elem_name=>$elem_href)
                                                        {
                                                                //echo $elem_name.' '.$elem_href.'<br>';
                                                                $prices = $this->ParesePrice($brend, $elem_href);
                                                                foreach($prices as $price)
                                                                {
                                                                        WorkWithDB::AddPrice($cod, 0, $grnum_value, 0, $elem_name, 0, $price[0], $price[1], $price[2], $price[3], $price[4], $price[5], $price[6], $price[7], $price[8], $price[9]);
                                                                        echo $price[1].' '.$price[2].'<br>';
                                                                        //AddPrice($tcodaxp, $grnum, $grnum_name, $pdgrnum, $elem_name, $numpart, $p_articul, $p_detail_name, $p_price, $p_weight, $p_delivery, $p_presence, $p_party, $p_period, $p_date, $p_direction)
                                                                }
                                                                
                                                                return;
                                                        }
                                                }
                                        }
                                }
                        }
                        echo 'Дата конца '.date("H:i:s").'<br>';
                }
                
                
                
                private function ParesePrice($brend, $html)
                {
                        $result = array();
                
                        //определение для конкретной модели
                        $dom = new domDocument;

                        $html = $this->proxy->GetPage($html);
                        @$dom->loadHTML($html);
                        
                        $next_html = '';
                        
                        //если страница перемещена
                        if (count($h2 = $dom->getElementsByTagName('h2')) == 1)
                        {
                                $html = $h2->item(0)->getElementsByTagName('a')->item(0)->getAttribute('href');
                                $html = $this->proxy->GetPage($html);
                                @$dom->loadHTML($html);
                        }
                        
                        //если страница с выбором альтернативных производителей
                        if (strpos($html, iconv("UTF-8", "Windows-1251", "История поиска деталей")) === false)
                        {
                                $tables = $dom->getElementsByTagName('table');
                                foreach($tables as $table)
                                {
                                        $trs = $table->getElementsByTagName('tr');
                                        echo cunt($trs).'<br>';
                                        foreach($trs as $tr)
                                        {               
                                                $tds = $tr->getElementsByTagName('td');
                                                if ($tds->length > 0)
                                                {
                                                                if (strpos($tds->item(0)->nodeValue, $brend) !== false)
                                                                //echo $name.'<br>';
                                                                //echo $tds->item(2)->getElementsByTagName('a')->item(0)->getAttribute('href');
                                                                $next_html = "www.choise.ru".$tds->item(2)->getElementsByTagName('a')->item(0)->getAttribute('href');
                                                }               
                                        }
                                }
                        }

                        if ($next_html <> '')
                        {
                                $html = $this->proxy->GetPage($next_html);
                                @$dom->loadHTML($html);
                        }
                        
                        //получаем цены всех деталей
                        $tables = $dom->getElementsByTagName('table');
                        foreach($tables as $table)
                        {
                                if ($table->hasAttribute('class') & ($table->getAttribute('class') == 'web_ar_datagrid'))
                                {
                                        $trs = $table->getElementsByTagName('tr');
                                        foreach($trs as $tr)
                                        {
                                                if ($tr->hasAttribute('class'))
                                                {
                                                        $tds = $tr->getElementsByTagName('td');
                                                        
                                                        $articul = $tds->item(1)->nodeValue; //артикул
                                                        $detail_name = trim($tds->item(2)->nodeValue); //название детали
                                                        $price = trim($tds->item(4)->nodeValue); //цена
                                                        $weight = $tds->item(5)->nodeValue; //вес (кг)
                                                        $delivery = $tds->item(6)->nodeValue; //дост. (р./кг)
                                                        $presence = $tds->item(7)->nodeValue; //наличие
                                                        $party = $tds->item(8)->nodeValue; //партия
                                                        $period = $tds->item(9)->nodeValue; //срок (раб.дн.)
                                                        $date = $tds->item(10)->nodeValue; //дата
                                                        $direction = $tds->item(13)->nodeValue; //направление
                                                        
                                                        $result[] = array ($articul, $detail_name, $price, $weight, $delivery, $presence, $party, $period, $date, $direction);
                                                        /*
                                                        echo $articul.'<br>';
                                                        echo $detail_name.'<br>';
                                                        echo $price.'<br>';
                                                        echo $weight.'<br>';
                                                        echo $delivery.'<br>';
                                                        echo $presence.'<br>';
                                                        echo $party.'<br>';
                                                        echo $period.'<br>';
                                                        echo $date.'<br>';
                                                        echo $direction.'<br>';
                                                        
                                                        echo '====='.'<br>';
                                                        */
                                                }
                                        }
                                }
                        }
                        return $result;
                }
                
                //Парсинг составных элементов подгруппы (шланг воздушный прав., шланг воздушный лев. и т.д.)
                private function ParserElemPdgrnum($html)
                {
                        $result = array();
                
                        $dom = new domDocument;
                        $html = $this->proxy->GetPage($html);
                        @$dom->loadHTML($html);
                        $trs = $dom->getElementsByTagName('tr');
                        foreach($trs as $tr)
                        {
                                if ($tr->hasAttribute('onclick'))
                                {
                                        $tds = $tr->getElementsByTagName('td');
                
                                        $name = $tds->item(1)->nodeValue;
                                        $href = $tds->item(2)->getElementsByTagName('a')->item(0)->getAttribute('href');
                                        
                                        //echo $name.' '.$href.'<br>';
                                        $result[$name] = $href;
                                }
                        }
                        return $result;
                }
                
                //Парсинг подгруппы группы деталей
                private function ParserPdgrnum($html)
                {
                        $result = array();

                        $dom = new domDocument;
                        $html = $this->proxy->GetPage($html);
                        @$dom->loadHTML($html);
                        $imgs = $dom->getElementsByTagName('img');
                        foreach($imgs as $img)
                        {
                                if ($img->hasAttribute('class') & ($img->getAttribute('class') == 'IMG1'))
                                {
                                        //echo $img->getAttribute('class').'<br>';
                                        //echo $img->parentNode->getAttribute('href').'<br>';
                                        $result[] = $img->parentNode->getAttribute('href');
                                }
                        }
                        return $result;
                }
                
                //Парсинг группы деталей (панель приборов, ходовая часть, кузов и т.д.)
                private function ParserGrnum($html)
                {
                        $result = array();
                
                        $dom = new domDocument;
                        $html = $this->proxy->GetPage($html);
                        @$dom->loadHTML($html);
                        $as = $dom->getElementsByTagName('a');
                        foreach($as as $a)
                        {
                                $ds = $a->getElementsByTagName('b');
                                if ($ds->length == 0)
                                {
                                        $value = $a->nodeValue;
                                        $href =  $a->getAttribute('href');
                                        if (trim($value) != '')
                                        {
                                                //echo $value.' '.$href.'<br>';
                                                $result[$value] = $href;
                                        }
                                }
                        }
                        return $result;
                }
                
                //Парсинг моделей
                private function Parser($_html, $_name)
                {
                        $result = array();

                        $dom = new domDocument;
                        $_html = str_replace(' ', '%20', $_html);

                        $html = $this->proxy->GetPage($_html);
                        //echo $html;
                        /*
                        $html = file_get_contents($_html);
                        if (strpos($html, 'Доступ временно прерван') !== false)
                        {
                                $time = 60*(60-date("i"))-date("s"); //число секунд до следующего часа
                                sleep($time); //ждем начала следующего часа
                                $html = file_get_contents($_html);
                        }
                        */
                        @$dom->loadHTML($html);
                        
                        $selects = $dom->getElementsByTagName('select');
                        foreach($selects as $select)
                        {
                                $name =  $select->getAttribute('name');
                                if ($name == $_name)
                                {
                                        $options = $select->getElementsByTagName('option');
                                        foreach($options as $option)
                                        {
                                                $value = $option->getAttribute('value');
                                                if ($value <> 'false')
                                                {
                                                        $result[] = $value;
                                                }
                                        }
                                }
                        }
                        
                        return $result;
                }
        }
        
        //класс для работы с базой данных
        class DB
        {
                const host = "localhost";
                const user = "avt";
                const pass = "avt";
                const db = "avt";

                //выполнить запрос
                static function Query($query)
                {
                        //открытие соединения
                        $link = mysql_connect(DB::host,DB::user,DB::pass) or die('Не могу соедениться с MySQL: '.mysql_error());
                        mysql_select_db(DB::db,$link) or die('Не могу выбрать базу: '.DB::db.'. Ошибка: '.mysql_error($link));

                        mysql_query($query) or die('Ошибка выполнения запроса: '.mysql_error());
                        
                        //закрытие соединения
                        mysql_close();
                }
                
                static function GetCods($query)
                {
                        //открытие соединения
                        $link = mysql_connect(DB::host,DB::user,DB::pass) or die('Не могу соедениться с MySQL: '.mysql_error());
                        mysql_select_db(DB::db,$link) or die('Не могу выбрать базу: '.DB::db.'. Ошибка: '.mysql_error($link));
                        
                        $cods = array();
                        
                        $result = mysql_query($query) or die('Query failed: ' . mysql_error());
                        
                        while ($line = mysql_fetch_array($result, MYSQL_NUM))
                        {
                                $cods[] = $line[0];
                        }
                        
                        //закрытие соединения
                        mysql_close();
                        
                        Return $cods;
                }
        }
        
        class WorkWithDB
        {
                static function AddModel($brend, $serie, $made, $kuzov, $fuel, $motor, $tcodaxp)
                {
                        DB::Query(iconv("UTF-8", "Windows-1251", "insert into avt_models (brend, serie, made, kuzov, fuel, motor, tcodaxp) 
                                values ('$brend', '$serie', $made, '$kuzov', '$fuel', '$motor', $tcodaxp)"));
                }
                
                static function ClearModels()
                {
                        DB::Query("delete from avt_models");
                }
                
                static function GetCods($brnd)
                {
                        $query = "select distinct tcodaxp from avt_models where brend = '".$brnd."'";
                        Return DB::GetCods($query);
                }
                
                static function ClearPrices()
                {
                        DB::Query("delete from avt_prices");
                }
                
                static function AddPrice($tcodaxp, $grnum, $grnum_name, $pdgrnum, $elem_name, $numpart, $p_articul, $p_detail_name, $p_price, $p_weight, $p_delivery, $p_presence, $p_party, $p_period, $p_date, $p_direction)
                {
                        DB::Query(iconv("UTF-8", "Windows-1251", "insert into avt_prices (tcodaxp, grnum, grnum_name, pdgrnum, elem_name, numpart, p_articul, p_detail_name, p_price, p_weight, p_delivery, p_presence, p_party, p_period, p_date, p_direction) 
                                values ($tcodaxp, $grnum, '$grnum_name', $pdgrnum, '$elem_name', $numpart, $p_articul, '$p_detail_name', '$p_price', '$p_weight', '$p_delivery', '$p_presence', '$p_party', '$p_period', '$p_date', '$p_direction')"));
                }
        }
        
        $choise = new Reader();
        $choise->UpdatePrice();

?>